﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Shapes;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls.Primitives;

namespace MontagsmalerApp.Utils
{
  public class Arc : Shape
  {
    public double StartAngle
    {
      get { return (double)GetValue(StartAngleProperty); }
      set { SetValue(StartAngleProperty, value); }
    }

    // Using a DependencyProperty as the backing store for StartAngle.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty StartAngleProperty =
        DependencyProperty.Register("StartAngle", typeof(double), typeof(Arc), new UIPropertyMetadata(0.0D));



    public double EndAngle
    {
      get { return (double)GetValue(EndAngleProperty); }
      set { SetValue(EndAngleProperty, value); }
    }

    // Using a DependencyProperty as the backing store for EndAngle.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty EndAngleProperty =
        DependencyProperty.Register("EndAngle", typeof(double), typeof(Arc), new UIPropertyMetadata(0.0D));

    public bool AngleInDegrees
    {
      get { return (bool)GetValue(AngleInDegreesProperty); }
      set { SetValue(AngleInDegreesProperty, value); }
    }

    // Using a DependencyProperty as the backing store for AngleInDegrees.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty AngleInDegreesProperty =
        DependencyProperty.Register("AngleInDegrees", typeof(bool), typeof(Arc), new UIPropertyMetadata(true));


    PathGeometry _geo = new PathGeometry();
    PathFigure _fig = new PathFigure();

    public Arc()
    {
      _fig.IsClosed = false;
      _geo.Figures.Add(_fig);
    }

    protected override Geometry DefiningGeometry
    {
      get
      {
        _fig.Segments.Clear();

        double start = StartAngle, end = EndAngle;
        if (AngleInDegrees)
        {
          start *= (Math.PI / 180.0D);
          end *= (Math.PI / 180.0D);
        }

        double step = 2.0D * (Math.PI / 180);

        _fig.StartPoint = calcPoint(start);

        for (double i = start + step; i <= end; i += (step * 3))
        {
          Point p1 = calcPoint(i - step * 2);
          Point p2 = calcPoint(i - step);
          Point p3 = calcPoint(i);

          BezierSegment seg = new BezierSegment();
          seg.Point1 = p1;
          seg.Point2 = p2;// new Point(p3.X - p1.X, p3.Y - p1.Y);
          seg.Point3 = p3;

          _fig.Segments.Add(seg);
        }

        return _geo;
      }
    }

    private Point calcPoint(double angle)
    {
      Rect r = LayoutInformation.GetLayoutSlot(this);
      double offX = (r.Width / 2.0D);
      double offY = (r.Height / 2.0D);
      double radX = (r.Width / 2.0D);
      double radY = (r.Height / 2.0D);

      Point p = new Point();
      p.X = radX * Math.Cos(angle) + offX;
      p.Y = radY * -Math.Sin(angle) + offY;
      return p;
    }

    private Point calcPoint2(double angle)
    {
      Rect r = LayoutInformation.GetLayoutSlot(this);

      double offX = (r.Width / 2.0D);
      double offY = (r.Height / 2.0D);
      double radX = (r.Width / 2.0D);
      double radY = (r.Height / 2.0D);

      Point p = new Point();
      p.X = radX * Math.Cos(angle) + offX;
      p.Y = radY * -Math.Sin(angle) + offY;
      return p;
    }

  }

}
